﻿using System;
using System.Text;
using GeoAPI.Geometries;

namespace YJKGridTopologyCal.Geometries.Implementation
{
	[Serializable]
	public class CoordinateArraySequence : ICoordinateSequence, ICloneable
	{
		public CoordinateArraySequence(Coordinate[] coordinates) : this(coordinates, 3)
		{
		}

		public CoordinateArraySequence(Coordinate[] coordinates, int dimension)
		{
			this._dimension = 3;
            //base..ctor();
			this.Coordinates = coordinates;
			this._dimension = dimension;
			if (coordinates == null)
			{
				this.Coordinates = new Coordinate[0];
			}
		}

		public CoordinateArraySequence(int size) : this(size, 3)
		{
		}

		public CoordinateArraySequence(int size, int dimension)
		{
			this._dimension = 3;
            //base.ctor();
			this.Coordinates = new Coordinate[size];
			this._dimension = dimension;
			for (int i = 0; i < size; i++)
			{
				this.Coordinates[i] = new Coordinate();
			}
		}

		public CoordinateArraySequence(ICoordinateSequence coordSeq)
		{
			this._dimension = 3;
            //base..ctor();
			if (coordSeq == null)
			{
				this.Coordinates = new Coordinate[0];
				return;
			}
			this._dimension = coordSeq.Dimension;
			this.Coordinates = new Coordinate[coordSeq.Count];
			for (int i = 0; i < this.Coordinates.Length; i++)
			{
				this.Coordinates[i] = coordSeq.GetCoordinateCopy(i);
			}
		}

		public int Dimension
		{
			get
			{
				return this._dimension;
			}
		}

		public Ordinates Ordinates
		{
			get
			{
				if (this._dimension != 3)
				{
					return Ordinates.XY;
				}
				return Ordinates.XYZ;
			}
		}

		public Coordinate GetCoordinate(int i)
		{
			return this.Coordinates[i];
		}

		public virtual Coordinate GetCoordinateCopy(int i)
		{
			return new Coordinate(this.Coordinates[i]);
		}

		public void GetCoordinate(int index, Coordinate coord)
		{
			coord.X = this.Coordinates[index].X;
			coord.Y = this.Coordinates[index].Y;
			coord.Z = this.Coordinates[index].Z;
		}

		public double GetX(int index)
		{
			return this.Coordinates[index].X;
		}

		public double GetY(int index)
		{
			return this.Coordinates[index].Y;
		}

		public double GetOrdinate(int index, Ordinate ordinate)
		{
			switch (ordinate)
			{
			case Ordinate.X:
				return this.Coordinates[index].X;
			case Ordinate.Y:
				return this.Coordinates[index].Y;
			case Ordinate.Z:
				return this.Coordinates[index].Z;
			default:
				return double.NaN;
			}
		}

		public virtual object Clone()
		{
			return new CoordinateArraySequence(this.GetClonedCoordinates(), this.Dimension);
		}

		protected Coordinate[] GetClonedCoordinates()
		{
			Coordinate[] array = new Coordinate[this.Count];
			for (int i = 0; i < this.Coordinates.Length; i++)
			{
				array[i] = (Coordinate)this.Coordinates[i].Clone();
			}
			return array;
		}

		public int Count
		{
			get
			{
				return this.Coordinates.Length;
			}
		}

		public void SetOrdinate(int index, Ordinate ordinate, double value)
		{
			switch (ordinate)
			{
			case Ordinate.X:
				this.Coordinates[index].X = value;
				return;
			case Ordinate.Y:
				this.Coordinates[index].Y = value;
				return;
			case Ordinate.Z:
				this.Coordinates[index].Z = value;
				return;
			default:
				return;
			}
		}

		public Coordinate[] ToCoordinateArray()
		{
			return this.Coordinates;
		}

		public Envelope ExpandEnvelope(Envelope env)
		{
			for (int i = 0; i < this.Coordinates.Length; i++)
			{
				env.ExpandToInclude(this.Coordinates[i]);
			}
			return env;
		}

		public ICoordinateSequence Reversed()
		{
			Coordinate[] array = new Coordinate[this.Count];
			for (int i = 0; i < this.Count; i++)
			{
				array[this.Count - i - 1] = new Coordinate(this.Coordinates[i]);
			}
			return new CoordinateArraySequence(array, this.Dimension);
		}

		public override string ToString()
		{
			if (this.Coordinates.Length != 0)
			{
				StringBuilder stringBuilder = new StringBuilder(17 * this.Coordinates.Length);
				stringBuilder.Append('(');
				stringBuilder.Append(this.Coordinates[0]);
				for (int i = 1; i < this.Coordinates.Length; i++)
				{
					stringBuilder.Append(", ");
					stringBuilder.Append(this.Coordinates[i]);
				}
				stringBuilder.Append(')');
				return stringBuilder.ToString();
			}
			return "()";
		}

		protected Coordinate[] Coordinates;

		private readonly int _dimension;
	}
}
